﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using DevExpress.XtraEditors;


namespace ProgramMain.Framework
{
    public static class BaseSecurity
    {
        public enum UserAccessType { ReadAccess, SupervisorAccess, ManagerAccess, TechAccess };

        public enum SecurityActionType { View, Edit, Delete, Approve };

        private static HashSet<UserAccessType> SecurityRights = new HashSet<UserAccessType>();

        public static string UserName = null;
        public static string UserEmail = null;
        public static int UserID = -1;

        public static bool LoadUserRights(string txtLogin, string txtPassword, bool bSavePassword)
        {
            try
            {
                SqlCommand sqlCmd = new SqlCommand();
                sqlCmd.Connection = GlobalData.SqlCon;
                sqlCmd.CommandType = CommandType.StoredProcedure;
                sqlCmd.CommandText = "[dbo].[usp_Authorize]";
                sqlCmd.Parameters.AddWithValue("@UserLogin", txtLogin);
                sqlCmd.Parameters.AddWithValue("@UserPassword", txtPassword);
                sqlCmd.Parameters.Add(new SqlParameter("@UserName", SqlDbType.NVarChar, 500, ParameterDirection.Output, true, 0, 0, "UserName", DataRowVersion.Default, null));
                sqlCmd.Parameters.Add(new SqlParameter("@UserID", SqlDbType.Int, 4, ParameterDirection.Output, true, 0, 0, "UserID", DataRowVersion.Default, null));
                sqlCmd.Parameters.Add(new SqlParameter("@Email", SqlDbType.NVarChar, 500, ParameterDirection.Output, true, 0, 0, "Email", DataRowVersion.Default, null));
                //sqlCmd.Prepare();
                SqlDataReader reader = sqlCmd.ExecuteReader();

                while (reader.Read())
                {
                    string operation = reader["OperationName"].ToString();
                    switch (operation)
                    {
                        case "readaccess":
                            {
                                SecurityRights.Add(UserAccessType.ReadAccess);
                            } break;
                        case "fullaccess":
                            {
                                SecurityRights.Add(UserAccessType.SupervisorAccess);
                            } break;
                        case "manageraccess":
                            {
                                SecurityRights.Add(UserAccessType.ManagerAccess);
                            } break;
                        case "techaccess":
                            {
                                SecurityRights.Add(UserAccessType.TechAccess);
                            } break;
                    }
                }
                reader.Close();
                if (sqlCmd.Parameters["@UserID"].Value != DBNull.Value)
                {
                    UserName = sqlCmd.Parameters["@UserName"].Value.ToString();
                    UserID = (Int32)sqlCmd.Parameters["@UserID"].Value;
                    UserEmail = sqlCmd.Parameters["@Email"].Value.ToString();
                    Properties.Settings.Default.UserName = txtLogin;
                    if (bSavePassword)
                    {
                        Properties.Settings.Default.UserPassword = Symmetric.Encrypt(txtPassword);
                    }
                    else
                    {
                        Properties.Settings.Default.UserPassword = "";
                    }
                    Properties.Settings.Default.Save();

                    return true;
                }
                XtraMessageBox.Show("У вас нет прав для доступа в систему");
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message);
            }
            return false;
        }

        public static string SettingsUserName
        {
            get
            {
                return Properties.Settings.Default.UserName;
            }
        }

        public static string SettingsUserPassword
        {
            get
            {
                return Symmetric.Decrypt(Properties.Settings.Default.UserPassword);
            }
        }

        public enum SuperBool { False, True, Super };

        public static SuperBool CheckSecurityAction(SecurityActionType actionType)
        {
            if (actionType == SecurityActionType.View)
            {
                if (SecurityRights.Contains(UserAccessType.SupervisorAccess))
                {
                    return SuperBool.Super;
                }
                if (SecurityRights.Contains(UserAccessType.ReadAccess)) //просмотр разрешен
                {
                    return SuperBool.True;
                }
            }  //по умолчанию изменения разрешены только администратору

            else if (SecurityRights.Contains(UserAccessType.SupervisorAccess))
            {
                return SuperBool.Super;
            }
            else if (SecurityRights.Contains(UserAccessType.TechAccess))
            {
                return SuperBool.True;
            }

            return SuperBool.False;
        }

        public static SuperBool CheckSecurityAccessType(UserAccessType access)
        {
            if (SecurityRights.Contains(UserAccessType.SupervisorAccess))
            {
                return SuperBool.Super;
            }
            if (SecurityRights.Contains(access))
            {
                return SuperBool.True;
            }

            return SuperBool.False;
        }

        public static void ShowSecurityWarning()
        {
            XtraMessageBox.Show("У вас недостаточно прав для выполнения данной операции", "Предупреждение!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }

        public static void ShowSecurityWarning(bool ShowWarning, SuperBool securityRes)
        {
            if (ShowWarning && securityRes == BaseSecurity.SuperBool.False)
            {
                BaseSecurity.ShowSecurityWarning();
            }
        }

        public static bool CheckSecuritySuperAction()
        {
            bool res = CheckSecurityAccessType(UserAccessType.SupervisorAccess) == SuperBool.Super;
            
            if (!res)
            {
                ShowSecurityWarning();
            }
            
            return res;
        }

        public static bool CheckSecurityViewAction()
        {
            bool res = CheckSecurityAction(SecurityActionType.View) != SuperBool.False;

            if (!res)
            {
                ShowSecurityWarning();
            }

            return res;
        }

        public static bool CheckSecurityTechAction()
        {
            return CheckSecurityTechAccess() != SuperBool.False || CheckSecuritySuperAction();
        }

        public static bool CheckSecurityManagerAction()
        {
            return CheckSecurityManagerAccess() != SuperBool.False || CheckSecuritySuperAction();
        }

        public static SuperBool CheckSecurityManagerAccess()
        {
            return CheckSecurityAccessType(UserAccessType.ManagerAccess);
        }

        public static SuperBool CheckSecurityTechAccess()
        {
            return CheckSecurityAccessType(UserAccessType.TechAccess);
        }
    }
}
